import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import os
from utils import resource_path, log_info, log_exception, log_warning
from services import PracticeService, FavoriteService, ExamService, HomeService, ExamStatisticsService
from .practice_view import PracticeView
from .exam_view import ExamView
from .messagebox_custom import CustomMessageBox
from .settings_view import SettingsView
from .exam_statistics import ExamStatisticsView
from app_state import app_state
from configs.config import FONT_CONFIG

class HomeView(tk.Frame):
    """首页视图类，负责首页界面的UI展示"""

    def __init__(self, root, application=None, style=None):
        super().__init__(root)
        self.root = root
        self.application = application
        self.style = style

        # 确保中文显示正常
        self.font = FONT_CONFIG['default']
        self.title_font = FONT_CONFIG['title']
        self.question_font = FONT_CONFIG['question']
        self.option_font = FONT_CONFIG['option']
        self.btn_font = FONT_CONFIG['button']
        self.img_width = 40
        self.img_height = 40

        # 初始化服务类
        self.practice_service = PracticeService()
        self.favorite_service = FavoriteService()
        self.exam_service = ExamService()
        self.exam_statistics_service = ExamStatisticsService()

        # 存储考试答案
        self.exam_answers = {}

        # 初始化用户答案变量
        self.user_answer = tk.StringVar(value='')

        # 考试已交卷标志
        self.exam_submitted = False

        # 创建主界面组件
        self.create_widgets()

    def create_widgets(self):
        """创建首页所有UI组件"""
        # 清空窗口
        for widget in self.root.winfo_children():
            widget.destroy()

        # 创建标题
        title_label = ttk.Label(self.root, text="业余无线电模拟考试系统",
                                font=self.title_font,
                                style="primary.TLabel")
        title_label.pack(pady=30)

        # 创建类别框架容器
        categories_frame = ttk.Frame(self.root)
        categories_frame.pack(pady=20, fill=tk.BOTH, expand=True, padx=20)

        # 创建A、B、C类题目框架
        self._create_category_frame(categories_frame, "A类题目", "A")
        self._create_category_frame(categories_frame, "B类题目", "B")
        self._create_category_frame(categories_frame, "C类题目", "C")

        # 创建功能按钮框架
        function_frame = ttk.Frame(self.root)
        function_frame.pack(pady=10)

        # 创建右上角设置按钮
        self._create_settings_button()

        # 显示用户信息和考试统计
        current_user = app_state.current_user
        if current_user:
            home_service = HomeService()
            formatted_last_login = home_service.format_last_login(current_user.last_login)
            self.show_user_info_and_statistics(current_user, formatted_last_login)

    def _create_category_frame(self, parent, title, category):
        """创建类别框架及其内部按钮

        Args:
            parent: 父容器
            title: 框架标题
            category: 类别标识(A/B/C)
        """
        frame = ttk.LabelFrame(parent, text=title, style="info.TLabelFrame")
        frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 练习模式按钮
        self._create_mode_button(frame, "practice_mode.png", "逐题练习",
                                lambda e: self.start_mode("practice", category))

        # 模拟考试按钮
        self._create_mode_button(frame, "exam_mode.png", "模拟考试",
                                lambda e: self.start_mode("exam", category))

        # 错题本按钮
        self._create_mode_button(frame, "error_book.png", "只做错题",
                                lambda e: self.start_mode("error", category))

        # 收藏本按钮
        self._create_mode_button(frame, "favorite_book.png", "只做收藏",
                                lambda e: self.start_mode("favorite", category))

    def _create_mode_button(self, parent, icon_name, text, command):
        """创建模式按钮

        Args:
            parent: 父容器
            icon_name: 图标文件名
            text: 按钮文本
            command: 点击事件回调
        """
        frame = tk.Frame(parent, cursor="hand2")
        frame.pack(pady=10)
        frame.bind("<Button-1>", command)

        # 加载图标
        icon_path = resource_path(os.path.join("icon", icon_name))
        icon = Image.open(icon_path)
        icon = icon.resize((self.img_width, self.img_height), Image.Resampling.LANCZOS)
        icon_photo = ImageTk.PhotoImage(icon)

        # 创建图标标签
        icon_label = tk.Label(frame, image=icon_photo, cursor="hand2")
        icon_label.image = icon_photo
        icon_label.bind("<Button-1>", command)
        icon_label.pack(side=tk.LEFT, padx=5)

        # 创建文本标签
        text_label = tk.Label(frame, text=text, fg="white", bg=frame['bg'],
                             cursor="hand2", font=self.btn_font)
        text_label.bind("<Button-1>", command)
        text_label.pack(side=tk.LEFT)

    def _create_settings_button(self):
        """创建设置按钮"""
        # 加载设置图标
        settings_img_path = resource_path(os.path.join('icon', 'setting.png'))
        settings_img = Image.open(settings_img_path)
        settings_img = settings_img.resize((30, 30), Image.LANCZOS)
        settings_photo = ImageTk.PhotoImage(settings_img)

        # 创建框架来包含设置图标
        settings_frame = tk.Frame(self.root)
        settings_frame.place(relx=0.95, rely=0.05, anchor=tk.NE)

        # 创建图片标签作为设置按钮
        settings_btn = tk.Label(settings_frame, image=settings_photo, cursor="hand2")
        settings_btn.image = settings_photo
        settings_btn.pack()
        settings_btn.bind("<Button-1>", lambda e: self.open_settings())

    def open_settings(self):
        # 创建设置窗口实例，传递当前应用实例作为参数
        SettingsView(self.root, self.application, self.practice_service)

    def start_mode(self, mode, category):
        app_state.current_mode = mode
        app_state.current_category = category
        # 重置考试已交卷标志
        self.exam_submitted = False
        
        if app_state.current_mode == "practice":
            self.practice_mode()
        elif app_state.current_mode == "exam":
            self.exam_mode()
        elif app_state.current_mode == "error":
            self.error_book_mode()
        elif app_state.current_mode == "favorite":
            self.favorite_mode()
        
    def practice_mode(self):
        # 设置当前模式为练习模式
        app_state.current_mode = 'practice'
        # 清空窗口
        for widget in self.root.winfo_children():
            widget.destroy()
        
        # 重新加载最新的练习进度
        self.load_practice_progress()
        
        # 使用PracticeService获取题目
        questions = self.practice_service.get_questions_by_category(app_state.current_category)
        if not questions:
            CustomMessageBox.showinfo("提示", f"没有找到{app_state.current_category}类题目", parent=self.root)
            self.create_widgets()
            return

        # 打乱选项并更新正确答案
        questions = self.practice_service.shuffle_options(questions)
        
        # 获取保存的进度
        current_index = app_state.practice_progress.get(app_state.current_category, 0)
        if current_index >= len(questions):
            current_index = 0
        
        # 使用PracticeView显示练习题目
        self.practice_view = PracticeView(
                self.root,
                practice_questions=questions,
            font=self.font,
            question_font=self.question_font,
            on_back=self.create_widgets
        )
        
    def exam_mode(self):
        # 清空窗口
        for widget in self.root.winfo_children():
            widget.destroy()

        # 创建返回按钮 - 图片形式
        back_img = Image.open(resource_path(os.path.join("icon", "back.png")))
        back_img = back_img.resize((30, 30), Image.Resampling.LANCZOS)  # 调整图片大小
        back_photo = ImageTk.PhotoImage(back_img)
        back_btn = tk.Label(self.root, image=back_photo, cursor="hand2")
        back_btn.image = back_photo  # 保持引用
        back_btn.bind("<Button-1>", lambda e: self.create_widgets())
        back_btn.pack(anchor=tk.NW, pady=10, padx=10)

        # 使用ExamService创建考试
        try:
            # 创建考试，获取考试ID、题目列表和配置
            exam_id, shuffled_questions, exam_config = self.exam_service.create_exam(app_state.current_user_id, app_state.current_category)
            if exam_id is None:
                CustomMessageBox.showinfo("提示", f"无法创建{app_state.current_category}类考试", parent=self.root)
                self.create_widgets()
                return

            # 创建ExamView显示考试界面
            self.exam_view = ExamView(
                self.root,
                exam_id=exam_id,
                exam_questions=shuffled_questions,
                exam_config=exam_config,
                on_back=self.create_widgets
            )
            self.exam_view.create_widgets()
        except Exception as e:
            log_exception(f"创建考试失败: {str(e)}")
            CustomMessageBox.showerror("错误", f"创建考试失败: {str(e)}", parent=self.root)
            self.create_widgets()
            return
        
    def error_book_mode(self):
        # 清空窗口
        for widget in self.root.winfo_children():
            widget.destroy()
        
        # 获取错题
        if app_state.current_user_id:
            # 使用practice_service获取错题
            error_questions = self.practice_service.get_error_questions(app_state.current_user_id, app_state.current_category)
            if not error_questions:
                CustomMessageBox.showinfo("提示", f"{app_state.current_category}类错题本为空", parent=self.root)
                self.create_widgets()
                return
            
            # 使用PracticeView显示错题
            self.practice_view = PracticeView(
                self.root,
                is_error=True,
                error_questions=error_questions,
                font=self.font,
                question_font=self.question_font,
                on_back=self.create_widgets
            )
        else:
            CustomMessageBox.showinfo("提示", "请先登录", parent=self.root)
            self.application.create_login_frame()
    
    def favorite_mode(self):
        # 清空窗口
        for widget in self.root.winfo_children():
            widget.destroy()
        
        # 获取收藏题目
        if app_state.current_user_id:
            favorite_questions = self.favorite_service.get_favorite_questions(app_state.current_user_id, app_state.current_category)
            if not favorite_questions:
                CustomMessageBox.showinfo("提示", f"{app_state.current_category}类收藏本为空", parent=self.root)
                self.create_widgets()
                return
            
            # 使用PracticeView显示收藏题目
            self.practice_view = PracticeView(
                self.root,
                practice_questions=favorite_questions,
                font=self.font,
                question_font=self.question_font,
                on_back=self.create_widgets
            )
        else:
            CustomMessageBox.showinfo("提示", "请先登录", parent=self.root)
            self.application.create_login_frame()

    def load_practice_progress(self):
        # 从AppState获取用户ID
        if app_state.current_user_id is None:
            return

        # 加载所有类别的练习进度
        categories = ['A', 'B', 'C']
        for category in categories:
            progress = self.practice_service.get_practice_progress(app_state.current_user_id, category)
            app_state.update_practice_progress(category, progress)

    def show_user_info_and_statistics(self, current_user, last_login):
        """显示用户信息、考试统计和退出登录按钮"""
        from configs.config import COPY_RIGHT
        
        # 创建用户信息框架
        user_info_frame = ttk.LabelFrame(self.root, text="用户信息", style="info.TLabelFrame")
        user_info_frame.pack(pady=20, fill=tk.X, padx=30)
        
        # 设置权重，使grid布局能够扩展
        user_info_frame.grid_columnconfigure(0, weight=1)
        user_info_frame.grid_columnconfigure(1, weight=1)
        user_info_frame.grid_rowconfigure(0, weight=1)
        user_info_frame.grid_rowconfigure(1, weight=1)
        
        # 用户基本信息框架 - 使用grid布局更高效地利用空间
        basic_info_frame = ttk.Frame(user_info_frame)
        basic_info_frame.grid(row=0, column=0, sticky="nsew", padx=20, pady=10)
        basic_info_frame.grid_columnconfigure(1, weight=1)  # 让内容列可扩展
        
        # 用户名
        ttk.Label(basic_info_frame, text="  用户名:", font=self.font, width=12, anchor=tk.W).grid(row=0, column=0, padx=(10, 15), pady=10, sticky=tk.W)
        ttk.Label(basic_info_frame, text=f"{current_user.username}", font=self.font, width=30).grid(row=0, column=1, padx=5, pady=10, sticky=tk.W)
        
        # 上次登录时间
        ttk.Label(basic_info_frame, text="上次登录:", font=self.font, width=12, anchor=tk.W).grid(row=1, column=0, padx=(10, 15), pady=10, sticky=tk.W)
        ttk.Label(basic_info_frame, text=f"{last_login}", font=self.font, width=30).grid(row=1, column=1, padx=5, pady=10, sticky=tk.W)
        
        # 考试统计信息框架 - 使用grid布局
        stats_frame = ttk.Frame(user_info_frame)
        stats_frame.grid(row=1, column=0, columnspan=2, sticky="nsew", padx=20, pady=(0, 10))
        
        # 初始化统计信息变量
        latest_exam_info = "暂无考试记录"
        best_scores = {"A": "未参加", "B": "未参加", "C": "未参加"}
        category = ""  # 初始化category变量
        score = 0
        total = 0
        minutes = 0
        seconds = 0
        
        # 获取考试统计数据
        if app_state.current_user_id:
            # 获取最近180天的考试数据
            exam_data = self.exam_statistics_service.get_exam_data(
                app_state.current_user_id, None, '180days')
            
            # 获取最近一次考试信息
            if exam_data:
                latest_exam = exam_data[-1]
                category = latest_exam['category']
                score = latest_exam['score']
                total = latest_exam['total_questions']
                duration = latest_exam['duration_seconds']
                minutes, seconds = divmod(int(duration), 60)
                latest_exam_info = f"最近考试: {category}类 {score}/{total}分 ({minutes}分{seconds}秒)"
            
            # 获取各类别的最佳成绩
            for category in ['A', 'B', 'C']:
                category_data = self.exam_statistics_service.get_exam_data(
                    app_state.current_user_id, category, '180days')
                if category_data:
                    max_score = max([exam['score'] for exam in category_data])
                    total_questions = category_data[0]['total_questions']
                    best_scores[category] = f"{max_score}/{total_questions}分"
        
        # 显示最近考试信息
        stats_frame.grid_columnconfigure(0, weight=0)  # 标签列固定宽度
        stats_frame.grid_columnconfigure(1, weight=1)  # 内容列可扩展
        
        # 最近考试信息（更宽的标签和内容，更好地利用空间）
        ttk.Label(stats_frame, text="最近考试:", font=self.font, width=12, anchor=tk.W).grid(row=0, column=0, padx=(10, 15), pady=12, sticky=tk.W)
        if exam_data:
            # 更紧凑的布局，更大的间距
            exam_content_frame = ttk.Frame(stats_frame)
            exam_content_frame.grid(row=0, column=1, sticky="ew", pady=12)
            exam_content_frame.grid_columnconfigure(0, weight=1)
            exam_content_frame.grid_columnconfigure(1, weight=1)
            exam_content_frame.grid_columnconfigure(2, weight=1)
            
            ttk.Label(exam_content_frame, text=f"{category}类", font=self.font, width=8).grid(row=0, column=0, padx=5)
            ttk.Label(exam_content_frame, text=f"{score}/{total}分", font=self.font, width=12).grid(row=0, column=1, padx=5)
            ttk.Label(exam_content_frame, text=f"({minutes}分{seconds}秒)", font=self.font).grid(row=0, column=2, padx=5, sticky=tk.W)
        else:
            ttk.Label(stats_frame, text="暂无考试记录", font=self.font).grid(row=0, column=1, padx=5, pady=12, sticky=tk.W)
        
        # 显示各类别最佳成绩（更宽的标签和更大的间距）
        ttk.Label(stats_frame, text="最佳成绩:", font=self.font, width=12, anchor=tk.W).grid(row=1, column=0, padx=(10, 15), pady=12, sticky=tk.W)
        
        # 为最佳成绩创建更紧凑的布局
        scores_frame = ttk.Frame(stats_frame)
        scores_frame.grid(row=1, column=1, sticky="ew", pady=12)
        scores_frame.grid_columnconfigure(0, weight=1)
        scores_frame.grid_columnconfigure(1, weight=1)
        scores_frame.grid_columnconfigure(2, weight=1)
        
        ttk.Label(scores_frame, text=f"A类: {best_scores['A']}", font=self.font, width=18).grid(row=0, column=0, padx=5)
        ttk.Label(scores_frame, text=f"B类: {best_scores['B']}", font=self.font, width=18).grid(row=0, column=1, padx=5)
        ttk.Label(scores_frame, text=f"C类: {best_scores['C']}", font=self.font, width=18).grid(row=0, column=2, padx=5, sticky=tk.W)
        
        # 退出登录按钮（图片形式）移至右下角
        logout_frame = tk.Frame(user_info_frame, cursor="hand2")
        logout_frame.grid(row=0, column=1, sticky="se", padx=20, pady=20)  # 使用grid布局放在右下角
        logout_frame.bind("<Button-1>", lambda e: self.logout())
        try:
            # 加载退出登录图标
            logout_img_path = resource_path(os.path.join('icon', 'logout.png'))
            logout_img = Image.open(logout_img_path)
            logout_img = logout_img.resize((30, 30), Image.LANCZOS)
            logout_photo = ImageTk.PhotoImage(logout_img)
            
            # 创建图片标签作为退出登录按钮
            logout_btn = tk.Label(logout_frame, image=logout_photo, cursor="hand2")
            logout_btn.image = logout_photo  # 保持引用
            logout_btn.pack(pady=5)
            logout_btn.bind("<Button-1>", lambda e: self.logout())
            
            # 添加退出登录文字
            logout_text = tk.Label(logout_frame, text="退出登录", font=self.font, cursor="hand2")
            logout_text.pack()
            logout_text.bind("<Button-1>", lambda e: self.logout())
        except Exception as e:
            # 如果图片加载失败，显示文本按钮作为备选
            log_warning(f"加载退出登录图标失败: {str(e)}")
            logout_btn = ttk.Button(logout_frame, text="退出登录", command=self.logout)
            logout_btn.pack(pady=10)
        
        # 居中显示版权信息
        copyright_frame = ttk.Frame(self.root)
        copyright_frame.pack(fill=tk.X, side=tk.BOTTOM, pady=10)
        copyright_label = ttk.Label(copyright_frame, text=COPY_RIGHT, font=self.font, style="light.TLabel")
        copyright_label.pack()
        
    def logout(self):
        """退出登录功能"""
        # 重置应用状态
        app_state.current_user = None
        app_state.current_user_id = None
        app_state.practice_progress = {}
        app_state.current_mode = None
        app_state.current_category = None
        
        # 创建登录界面
        self.application.create_login_frame()
